/* ----------------------------------------------------------
 * 文件名称：FXMLDocumentController.java
 * 
 * 作者：秦建辉
 * 
 * 微信：splashcn
 * 
 * 博客：http://www.firstsolver.com/wordpress/
 * 
 * 开发环境：
 *      NetBeans 8.1
 *      JDK 8u102
 *      
 * 版本历史：
 *      V1.1    2016年08月10日
 *              SDK更新
 *
 *      V1.0    2015年12月10日
 *              验证服务器端
------------------------------------------------------------ */
package Splash;

import Com.FirstSolver.Security.Utils;
import Com.FirstSolver.Splash.FaceIdProtocolCodecFactory;
import Com.FirstSolver.Splash.FaceId_Item;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.Log4jLoggerFactory;

import com.huajx.http.kit.HttpKit;
import com.huajx.kit.Prop;
import com.huajx.kit.PropKit;
import com.huajx.kit.StrKit;

@SuppressWarnings("restriction")
public class FXMLDocumentController extends IoHandlerAdapter implements Initializable {

	private final static Logger logger = LoggerFactory.getLogger(FXMLDocumentController.class);
	// 序列号属性键
	private static final AttributeKey KEY_SERIALNUMBER = new AttributeKey(FXMLDocumentController.class, "SerialNumber");

	private final String DeviceCharset = "GBK";

	private boolean IsServerRunning = false;

	public IoAcceptor mTcpServer = null;

	@FXML
	private ComboBox<String> comboBoxServerIP;

	@FXML
	private TextField textFieldServerPort;

	@FXML
	private TextArea textAreaAnswer;

	@FXML
	private Button buttonStartListener;

	@FXML
	private CheckBox checkBoxPostPhoto;

	@FXML
	private TextArea textAreaDeviceCommand;

	@FXML
	private CheckBox checkBoxPassiveEncryption;
	
	private String schoolId;
	private String schoolName;
	
	private String serverUrl="http://localhost:8080/jxt-weixin";

	@FXML
	private void handleButtonClearAction(ActionEvent event) {
		textAreaAnswer.clear();
	}

	@FXML
	private void handleButtonStartListenerAction(ActionEvent event) throws IOException, Exception {
		if (IsServerRunning) {
			if (mTcpServer != null) {
				mTcpServer.dispose(true);
				mTcpServer = null;
			}
			IsServerRunning = false;
			buttonStartListener.setText("开始侦听");
		} else { // 创建侦听服务器
			mTcpServer = new NioSocketAcceptor();
			mTcpServer.getFilterChain().addLast("codec", new ProtocolCodecFilter(
					new FaceIdProtocolCodecFactory(DeviceCharset, true, checkBoxPassiveEncryption.isSelected())));
			mTcpServer.setHandler(this);
			mTcpServer.bind(new InetSocketAddress(InetAddress.getByName(comboBoxServerIP.getValue().toString()),
					Integer.parseInt(textFieldServerPort.getText())));

			IsServerRunning = true;
			buttonStartListener.setText("停止侦听");
		}
	}
	
	String record = "";

	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
		// 显示消息内容
		String Answer = message.toString();
		printMessage(message, false);
//		printMessage(session.isClosing(), false);
//		textAreaAnswer.appendText(Answer + "\r\n");
		logger.info(Answer);

		if (Answer.startsWith("PostRecord")) {
			// 获取设备序列号
			String SerialNumber = FaceId_Item.GetKeyValue(Answer, "sn");
			session.setAttribute(KEY_SERIALNUMBER, SerialNumber);
			
			// 服务器回应
			if (checkBoxPostPhoto.isSelected()) {
				session.write("Return(result=\"success\" postphoto=\"true\")");
			} else {
				session.write("Return(result=\"success\" postphoto=\"false\")");
			}
		} else if (Answer.startsWith("Record")) {
			// 获取考勤记录
			// String SerialNumber =
			// session.getAttribute(KEY_SERIALNUMBER).toString();
			record = Answer;
			//获取设备序列号
			Object SerialNumber = session.getAttribute(KEY_SERIALNUMBER);
			String sn = String.valueOf(SerialNumber);
			// 处理卡点数据
			HttpKit.post(serverUrl + "/a/hanvon", message.toString(), schoolId, schoolName,sn);
			// 服务器回应 
			session.write("Return(result=\"success\")");
		} else if (Answer.startsWith("PostEmployee")) {
			// 准备上传人员信息
			record = Answer;
			String SerialNumber = FaceId_Item.GetKeyValue(Answer, "sn");
			session.setAttribute(KEY_SERIALNUMBER, SerialNumber);
			
			// 服务器回应
			session.write("Return(result=\"success\")");
		} else if (Answer.startsWith("Employee")) {
			// 读取人员信息(登记修改人脸)
			record = Answer;
			//获取设备序列号
			Object SerialNumber = session.getAttribute(KEY_SERIALNUMBER);
			String sn = String.valueOf(SerialNumber);
			// 处理卡点数据
			HttpKit.post(serverUrl + "/a/face/saveFace", message.toString(), schoolId, schoolName,sn);
			// 服务器回应
			session.write("Return(result=\"success\")");
		} else if (Answer.startsWith("GetRequest")) {
			// 获取设备序列号
			String SerialNumber = FaceId_Item.GetKeyValue(Answer, "sn");
			session.setAttribute(KEY_SERIALNUMBER, SerialNumber);
			// 处理命令下发
			Object content = HttpKit.get(serverUrl + "/a/instruction/instructions?sn="+SerialNumber);
			if(null != content){
				JSONArray array = new JSONArray(content.toString()); 
				StringBuffer con = new StringBuffer();//修改的指令表记录
				StringBuffer commandSet = new StringBuffer("SetNameTable(");//需执行的指令
				StringBuffer commandAdd = new StringBuffer("AddNameTable(");
				StringBuffer commandDel = new StringBuffer("DeleteEmployee(");
				StringBuffer commandSetface = new StringBuffer("SetEmployee(");
				for(int i = 0;i<array.length();i++){
		    	    JSONObject json = array.getJSONObject(i);
		        	String description =json.getString("description");   //需要执行的命令类型
		        	String ids = json.getString("ids");//指令记录ID
		        	String id = json.getString("id");//修改前的ID
		        	String modifId = json.getString("modifId");//修改后的id
		        	String address = json.getString("address");//修改的楼栋
		        	//String devId = json.getString("devId");//执行的机型号
		        	String names = json.getString("names");//人员名称
		        	
		        	//生成指令
		        	if("update".equals(description)){
		        		
		        			commandSet.append(id).append("=\"").append(names).append("\" ");
		        		
		        	}else if("add".equals(description)){
		        		if(StrKit.notBlank(modifId)||StrKit.notBlank(address)){
		        			if(StrKit.notBlank(address)){
		        				modifId = id;
		        			}
		        			Object faces = HttpKit.get(serverUrl + "/a/face/getFace?sn="+SerialNumber+"&&id="+id);
		        			if(null != faces){
		        				JSONArray arr = new JSONArray(faces.toString()); 
		        				for(int j = 0;j<arr.length();j++){
		        		    	    JSONObject fjson = arr.getJSONObject(j);
		        		        	String cardNum =fjson.getString("cardNum");
		        		        	String authority =fjson.getString("authority");
		        		        	String checkType =fjson.getString("checkType");
		        		        	String calid =fjson.getString("calid");
		        		        	String face_data=fjson.getString("face_data");
		        		        	Object data = HttpKit.get(face_data);
		        		        	commandSetface.append("id=\"").append(modifId).append("\" ").append("name=\"").append(names).append("\" ").append("calid=\"").append(calid).append("\" ").append("card_num=\"").append(cardNum).append("\" ").append("authority=\"").append(authority).append("\" ").append("check_type=\"").append(checkType).append("\" ").append("opendoor_type=\"face&card\" ").append(data.toString());
		        		        	
		        		        	logger.info(face_data);
		        		        	
		        				}	
		        				if(StrKit.notBlank(modifId)){
			        				Object result = HttpKit.get(serverUrl + "/a/face/updateFace?id="+id+"&&modifId="+modifId);
			        			}
		        			}
		        		}else{
		        			commandAdd.append(id).append("=\"").append(names).append("\" ");
		        		}
		        	}else if("delete".equals(description)){
		        		commandDel.append("id=\"").append(id).append("\" ");
		        	}
		        	//保存指令表需要修改状态的记录ID
		        	if(StrKit.notBlank(ids)){
		        		con.append(ids);
		        	}
		        	if(i<array.length()-1){
		        		con.append(",");
	        		}
		        }
		        session.setAttribute("con", con.toString());
		        //判断是否需要执行此指令
		        if(commandSet.toString().indexOf("=") != -1){
		        	commandSet.append(")");
			        System.out.println(commandSet);
			        if (!Utils.IsNullOrEmpty(commandSet.toString())) {
						session.write(commandSet);
					}
	        	}
		        if(commandAdd.toString().indexOf("=") != -1){
	        		commandAdd.append(")");
			        System.out.println(commandAdd);
			        if (!Utils.IsNullOrEmpty(commandAdd.toString())) {
						session.write(commandAdd);
					}
	        	}
		        if(commandDel.toString().indexOf("=") != -1){
	        		commandDel.append(")");
			        System.out.println(commandDel);
			        if (!Utils.IsNullOrEmpty(commandDel.toString())) {
						session.write(commandDel);
					}
	        	}
		        if(commandSetface.toString().indexOf("=") != -1){
		        	commandSetface.append("\")");
			        System.out.println(commandSetface);
			        if (!Utils.IsNullOrEmpty(commandSetface.toString())) {
						session.write(commandSetface);
					}
	        	}
			}
//		String Command = textAreaDeviceCommand.getText();
//			if (!Utils.IsNullOrEmpty(Command)) {
//				session.write(Command);
////				textAreaDeviceCommand.clear();
//			}
		} else if(Answer.startsWith("Return")){
			//获取设备序列号
			Object SerialNumber = session.getAttribute(KEY_SERIALNUMBER);
			String sn = String.valueOf(SerialNumber);
			String result  = FaceId_Item.GetKeyValue(Answer, "result");
			Object con = session.getAttribute("con");
			String content = String.valueOf(con);
			if("success".equals(result)&&StrKit.notBlank(content)){
			 
				HttpKit.post(serverUrl + "/a/instruction/updateStatus", content, schoolId, schoolName,sn);
			
			}
		}else if (Answer.startsWith("Quit")) {
			// 结束会话
			session.closeNow();
		}
//		record = Answer;
	}
	
	
	void printMessage(Object message, boolean isClear) {
		javafx.application.Platform.runLater(new Runnable() {
			@Override
			public void run() {
				// 更新JavaFX的主线程的代码放在此处
				if(isClear){
					textAreaAnswer.setText(message.toString() + "\n");
				}else{
					textAreaAnswer.appendText(message.toString() + "\n");
				}
				
			}
		});
	}
	private boolean config_dev = true;
	private void initConfig(){
		Prop prop = PropKit.use("config.properties");
		
		config_dev = prop.getBoolean(Constant.config_dev, true);
		
		if(!config_dev){
			serverUrl = prop.get(Constant.server_url);
		}
		schoolId = prop.get(Constant.school_id);
		schoolName = prop.get(Constant.school_name);
	}

	@Override
	public void initialize(URL url, ResourceBundle rb) {
		initConfig();
		// 设置服务器地址
		try {
			List<String> IPList = new LinkedList<>();
			Enumeration<NetworkInterface> InterfaceList = NetworkInterface.getNetworkInterfaces();
			while (InterfaceList.hasMoreElements()) {
				NetworkInterface iFace = InterfaceList.nextElement();
				if (iFace.isLoopback() || iFace.isVirtual() || iFace.isPointToPoint() || !iFace.isUp())
					continue;

				Enumeration<InetAddress> AddrList = iFace.getInetAddresses();
				while (AddrList.hasMoreElements()) {
					InetAddress address = AddrList.nextElement();
					if (address instanceof Inet4Address) {
						String ip = address.getHostAddress();
						if(ip.indexOf("192.168")!=-1){
							IPList.add(ip);
						}
					}
				}
			}

			if (!IPList.isEmpty()) {
				comboBoxServerIP.setItems(FXCollections.observableList(IPList));
				comboBoxServerIP.getSelectionModel().selectFirst();
			}
		} catch (SocketException ex) {
			// 异常处理
		} finally {
			try {
				handleButtonStartListenerAction(null);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	
}
